// DriveNotes. Copyright (c) 2011, Andrei Senchuk. All rights reserved.
package net.taviscaron.drivenotes.web.action;

import java.io.IOException;
import java.util.GregorianCalendar;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.taviscaron.drivenotes.shared.exceptions.InvalidEntityException;
import net.taviscaron.drivenotes.shared.model.entity.Car;
import net.taviscaron.drivenotes.shared.model.entity.Service;
import net.taviscaron.drivenotes.shared.model.entity.User;
import net.taviscaron.drivenotes.shared.service.GarageService;
import net.taviscaron.drivenotes.shared.service.ServiceService;
import net.taviscaron.drivenotes.web.converter.FormConverter;
import net.taviscaron.drivenotes.web.converter.InvalidFormException;
import net.taviscaron.drivenotes.web.core.Constants;
import net.taviscaron.drivenotes.web.forward.ActionRedirect;
import net.taviscaron.drivenotes.web.forward.RequestForwarder;
import net.taviscaron.drivenotes.web.forward.ViewForward;
import org.springframework.beans.factory.annotation.Required;

/**
 * Service edit action
 * @author Andrei Senchuk
 */
public class ServiceEditAction implements Action {
    public enum Error {
        BAD_PARAMS;
    }

    private ServiceService serviceService;
    private GarageService garageService;
    private FormConverter<Service> serviceConverter;

    @Required
    public void setServiceConverter(FormConverter<Service> serviceConverter) {
        this.serviceConverter = serviceConverter;
    }

    @Required
    public void setGarageService(GarageService garageService) {
        this.garageService = garageService;
    }

    @Required
    public void setServiceService(ServiceService serviceService) {
        this.serviceService = serviceService;
    }

    public RequestForwarder doAction(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String subaction = request.getParameter(Constants.SUBACTION_PARAM_NAME);
        if(subaction == null) {
            return newEditAction(request, response);
        } else if ("save".equals(subaction)) {
            return saveAction(request, response);
        } else if ("del".equals(subaction)) {
            return deleteAction(request, response);
        } else {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "bad subaction");
            return null;
        }
    }

    public RequestForwarder deleteAction(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Long id = null;
        try {
            id = Long.valueOf(request.getParameter("serviceId"));
        } catch (NumberFormatException e) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return null;
        }

        User user = (User)request.getAttribute(Constants.AUTHORIZED_USER_ATTR_NAME);
        Service service = serviceService.findById(id);
        if(service != null && service.getCar().getOwner().getId().equals(user.getId())) {
            serviceService.removeServiceById(service.getId());
        }
        return new ActionRedirect("service");
    }

    public RequestForwarder saveAction(HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = (User)request.getAttribute(Constants.AUTHORIZED_USER_ATTR_NAME);
        Service service = null;
        try {
            Long carId;
            service = serviceConverter.convert(request.getParameterMap());
            if(service.getId() == null) {
                service.setDate(GregorianCalendar.getInstance().getTime());
                try {
                    carId = Long.valueOf(request.getParameter("carId"));
                } catch (NumberFormatException e) {
                    response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                    return null;
                }
            } else {
                Service original = serviceService.findById(service.getId());
                carId = original.getCar().getId();
                service.setDate(original.getDate());
            }

            Car car = garageService.findCar(carId, user);
            if(car == null) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return null;
            }

            service.setCar(car);
            serviceService.saveService(service);
        } catch (InvalidFormException e) {
            request.setAttribute("error", Error.BAD_PARAMS);
            return new ViewForward("serviceEdit");
        } catch (InvalidEntityException e) {
            request.setAttribute("error", e.getReason());
            return new ViewForward("serviceEdit");
        }
        return new ActionRedirect("service");
    }

    public RequestForwarder newEditAction(HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = (User)request.getAttribute(Constants.AUTHORIZED_USER_ATTR_NAME);
        String carIdStr = request.getParameter("carId");
        String serviceIdStr = request.getParameter("serviceId");
        if(carIdStr != null) {
            // new service record
            Long carId;
            try {
                carId = Long.valueOf(carIdStr);
            } catch (NumberFormatException e) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return null;
            }

            Car car = garageService.findCar(carId, user);
            if(car == null) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return null;
            }

            request.setAttribute("carId", carId);
        } else if (serviceIdStr != null) {
            // edit
            Long serviceId;
            try {
                serviceId = Long.valueOf(serviceIdStr);
            } catch (NumberFormatException e) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return null;
            }

            Service service = serviceService.findById(serviceId);
            if(service == null || !service.getCar().getOwner().getId().equals(user.getId())) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return null;
            }

            request.setAttribute("service", service);
        } else {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return null;
        }
        return new ViewForward("serviceEdit");
    }
}
